home *** CD-ROM | disk | FTP | other *** search
- /* bobfcn.c - built-in classes and functions */
- /*
- Copyright (c) 1991, by David Michael Betz
- All rights reserved
- */
-
- #include "bob.h"
-
- /* argument check macros */
- #define argcount(n,cnt) { if ((n) != (cnt)) wrongcnt(n,cnt); }
-
- /* stdio dispatch table */
- IODISPATCH fileio = {
- fclose,
- fgetc,
- fputc,
- fputs
- };
-
- /* external variables */
- extern VALUE symbols;
-
- /* forward declarations */
- #ifdef __STDC__
- static int xtypeof(int argc);
- static int xgc(int argc);
- static int xnewvector(int argc);
- static int xnewstring(int argc);
- static int xsizeof(int argc);
- static int xfopen(int argc);
- static int xfclose(int argc);
- static int xgetc(int argc);
- static int xputc(int argc);
- static int xprint(int argc);
- static int xgetarg(int argc);
- static int xsystem(int argc);
- #else
- int xtypeof(),xgc();
- int xnewvector(),xnewstring(),xsizeof(),xprint(),xgetarg(),xsystem();
- int xfopen(),xfclose(),xgetc(),xputc();
- #endif
-
- /* init_functions - initialize the internal functions */
- void init_functions()
- {
- add_function("typeof",xtypeof);
- add_function("gc",xgc);
- add_function("newvector",xnewvector);
- add_function("newstring",xnewstring);
- add_function("sizeof",xsizeof);
- add_function("fopen",xfopen);
- add_function("fclose",xfclose);
- add_function("getc",xgetc);
- add_function("putc",xputc);
- add_function("print",xprint);
- add_function("getarg",xgetarg);
- add_function("system",xsystem);
- }
-
- /* add_function - add a built-in function */
- void add_function(name,fcn)
- char *name; int (*fcn)();
- {
- DICT_ENTRY *sym;
- sym = addentry(&symbols,name,ST_SFUNCTION);
- set_code(&sym->de_value,fcn);
- }
-
- /* xtypeof - get the data type of a value */
- static int xtypeof(argc)
- int argc;
- {
- argcount(argc,1);
- set_integer(&sp[1],sp->v_type);
- ++sp;
- }
-
- /* xgc - invoke the garbage collector */
- static int xgc(argc)
- int argc;
- {
- argcount(argc,0);
- gc();
- set_nil(sp);
- }
-
- /* xnewvector - allocate a new vector */
- static int xnewvector(argc)
- int argc;
- {
- int size;
- argcount(argc,1);
- chktype(0,DT_INTEGER);
- size = sp->v.v_integer;
- set_vector(&sp[1],newvector(size));
- ++sp;
- }
-
- /* xnewstring - allocate a new string */
- static int xnewstring(argc)
- int argc;
- {
- int size;
- argcount(argc,1);
- chktype(0,DT_INTEGER);
- size = sp->v.v_integer;
- set_string(&sp[1],newstring(size));
- ++sp;
- }
-
- /* xsizeof - get the size of a vector or string */
- static int xsizeof(argc)
- int argc;
- {
- argcount(argc,1);
- switch (sp->v_type) {
- case DT_VECTOR:
- set_integer(&sp[1],sp->v.v_vector->vec_size);
- break;
- case DT_STRING:
- set_integer(&sp[1],sp->v.v_string->str_size);
- break;
- default:
- break;
- }
- ++sp;
- }
-
- /* xfopen - open a file */
- static int xfopen(argc)
- int argc;
- {
- char name[50],mode[10];
- FILE *fp;
- argcount(argc,2);
- chktype(0,DT_STRING);
- chktype(1,DT_STRING);
- getcstring(name,sizeof(name),&sp[1]);
- getcstring(mode,sizeof(mode),&sp[0]);
- if ((fp = fopen(name,mode)) == NULL)
- set_nil(&sp[2]);
- else
- set_iostream(&sp[2],newiostream(&fileio,fp));
- sp += 2;
- }
-
- /* xfclose - close a file */
- static int xfclose(argc)
- int argc;
- {
- argcount(argc,1);
- chktype(0,DT_IOSTREAM);
- set_integer(&sp[1],iosclose(&sp[0]));
- ++sp;
- }
-
- /* xgetc - get a character from a file */
- static int xgetc(argc)
- int argc;
- {
- argcount(argc,1);
- chktype(0,DT_IOSTREAM);
- set_integer(&sp[1],iosgetc(&sp[0]));
- ++sp;
- }
-
- /* xputc - output a character to a file */
- static int xputc(argc)
- int argc;
- {
- argcount(argc,2);
- chktype(0,DT_IOSTREAM);
- chktype(1,DT_INTEGER);
- set_integer(&sp[2],iosputc((int)sp[1].v.v_integer,&sp[0]));
- sp += 2;
- }
-
- /* xprint - generic print function */
- static int xprint(argc)
- int argc;
- {
- extern VALUE stdout_iostream;
- int n;
- for (n = argc; --n >= 0; )
- print1(&stdout_iostream,FALSE,&sp[n]);
- sp += argc;
- set_nil(sp);
- }
-
- /* print1 - print one value */
- print1(ios,qflag,val)
- VALUE *ios; int qflag; VALUE *val;
- {
- char name[TKNSIZE+1],buf[200],*p;
- VALUE *class;
- int len;
- switch (val->v_type) {
- case DT_NIL:
- iosputs("nil",ios);
- break;
- case DT_CLASS:
- getcstring(name,sizeof(name),clgetname(val));
- sprintf(buf,"#<Class-%s>",name);
- iosputs(buf,ios);
- break;
- case DT_OBJECT:
- sprintf(buf,"#<Object-%lx>",objaddr(val));
- iosputs(buf,ios);
- break;
- case DT_VECTOR:
- sprintf(buf,"#<Vector-%lx>",vecaddr(val));
- iosputs(buf,ios);
- break;
- case DT_INTEGER:
- sprintf(buf,"%ld",val->v.v_integer);
- iosputs(buf,ios);
- break;
- case DT_STRING:
- if (qflag) iosputc('"',ios);
- p = strgetdata(val);
- len = strgetsize(val);
- while (--len >= 0)
- iosputc(*p++,ios);
- if (qflag) iosputc('"',ios);
- break;
- case DT_BYTECODE:
- sprintf(buf,"#<Bytecode-%lx>",vecaddr(val));
- iosputs(buf,ios);
- break;
- case DT_CODE:
- sprintf(buf,"#<Code-%lx>",val->v.v_code);
- iosputs(buf,ios);
- break;
- case DT_VAR:
- class = digetclass(degetdictionary(val));
- if (!isnil(class)) {
- getcstring(name,sizeof(name),clgetname(class));
- sprintf(buf,"%s::",name);
- iosputs(buf,ios);
- }
- getcstring(name,sizeof(name),degetkey(val));
- iosputs(name,ios);
- break;
- case DT_IOSTREAM:
- sprintf(buf,"#<Stream-%lx>",val->v.v_iostream);
- iosputs(buf,ios);
- break;
- default:
- error("Undefined type: %d",valtype(val));
- }
- }
-
- /* xgetarg - get an argument from the argument list */
- static int xgetarg(argc)
- int argc;
- {
- extern char **bobargv;
- extern int bobargc;
- int i;
- argcount(argc,1);
- chktype(0,DT_INTEGER);
- i = sp[0].v.v_integer;
- if (i >= 0 && i < bobargc)
- set_string(&sp[1],makestring(bobargv[i]));
- else
- set_nil(&sp[1]);
- ++sp;
- }
-
- /* xsystem - execute a system command */
- static int xsystem(argc)
- int argc;
- {
- char cmd[133];
- argcount(argc,1);
- chktype(0,DT_STRING);
- getcstring(cmd,sizeof(cmd),&sp[0]);
- set_integer(&sp[1],system(cmd));
- ++sp;
- }
-
- /* wrongcnt - report wrong number of arguments */
- void wrongcnt(n,cnt)
- int n,cnt;
- {
- if (n < cnt)
- error("Too many arguments");
- else if (n > cnt)
- error("Too few arguments");
- }